package com.zz.springboot.util;

import com.zz.springboot.dto.DataDTO;
import com.zz.springboot.exception.BizException;
import com.zz.springboot.initializer.DataInitializer;
import com.zz.springboot.resp.enums.RespCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class DataDealUtils {
    /**
     * 中文字符处理
     *
     * @param originData
     * @return
     */
    public static String chineseCharacterProceess(String originData){
        /** ------------ 1.中文字符处理 ------------ **/
        //1.处理汉字数字，如将“1/2/3各五”转为“1/2/3各5”
        String data = ChineseNumberConverter.convertChineseNumbersToArabic(originData);
        //2.处理金额单位及其它字符：元、块、快、米、澳、奥、们、门、香、港
        data = data.replace("元", "").replace("块", "").replace("快", "").replace("米", "").
                replace("奥", "").replace("澳", "").replace("们", "").replace("门", "").
                replace("香", "").replace("港", "").replace("买","");
        return data;
    }

    /**
     * 将原始数据封装为实体类
     *
     * @param dataList
     * @return
     */
    public static List<DataDTO> listToModel(List<String> dataList) {
        List<DataDTO> dataDtos = new ArrayList<>();
        for (int i = 0; i < dataList.size(); i++) {
            String[] metaArr = dataList.get(i).split(":");

            DataDTO dataDTO = new DataDTO();
            int num = Integer.valueOf(metaArr[0]);  //Integer.valueOf("01")能自动处理前导0
            float buyMoney = Float.valueOf(metaArr[1]);
            dataDTO.setNum(num);
            dataDTO.setBuyMoney(buyMoney);

            dataDtos.add(dataDTO);
        }
        return dataDtos;
    }

    /**
     * 从字符串中解析生肖对应的号码
     *
     * @param animal 生肖
     * @return
     */
    public static List<Integer> extraNumForAnimals(String animal) {
        if (animal.length() != 1) {
            log.error("******生肖的字数只能为1，如“鼠”，不能写成“老鼠”");
            throw new BizException(RespCodeEnum.CONTENTS_FORMAT_INCORRECT);
        }

        List<Integer> nums = DataInitializer.getAnimalMap().get(animal);
        log.info("包" + animal + "共有号码为：" + nums);
        return nums;
    }

    /**
     * 解析单双对应的号码
     *
     * @param key 单、双
     * @return
     */
    public static List<Integer> extraNumForOddsOrEvens(String key) {
        if (key.length() != 1) {
            log.error("******请明确包双还是包单");
            throw new BizException(RespCodeEnum.CONTENTS_FORMAT_INCORRECT);
        }

        List<Integer> nums = DataInitializer.getOddsEvensMap().get(key);
        log.info("包" + key + "共有号码为：" + nums);

        return nums;
    }

    /**
     * 解析大小对应的号码
     *
     * @param key 大、小
     * @return
     */
    public static List<Integer> extraNumForBigLittle(String key) {
        if (key.length() != 1) {
            log.error("******请明确包大还是包小");
            throw new BizException(RespCodeEnum.CONTENTS_FORMAT_INCORRECT);
        }
        List<Integer> nums = DataInitializer.getBigLittleMap().get(key);
        log.info("包" + key + "共有号码为：" + nums);
        return nums;
    }



    /**
     * 从字符串中抽离出金额
     *
     * @param str
     * @return
     */
    public static Float extractMoneyFromStr(String str) {
        String regEx = "\\d+";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);

        String money = "";
        String lastMatch = "";
        // 查找最后一个连续的数字序列
        while (m.find()) {
            lastMatch = m.group();
        }
        money = lastMatch;

        if (!StringUtils.hasText(money)) {
            log.error("******对应项未输入金额！");
            throw new BizException(RespCodeEnum.CONTENTS_FORMAT_INCORRECT);
        }

        return Float.valueOf(money);
    }

    /**
     * 保留2位小数
     *
     * @param money 金额
     * @return
     */
    public static Float keepPoint(Float money) {
        return ((float) Math.round(money * 100)) / 100;
    }

    /**
     * 计算初版数据
     *
     * @param dataDTO     原始数据
     * @param eatMaxValue 每个号子消化的最大值
     */
    public static void calculateInitialValue(DataDTO dataDTO, Integer eatMaxValue) {
        if (dataDTO.getBuyMoney() <= eatMaxValue) {
            dataDTO.setExcludeMoney(0);
            dataDTO.setEatMoney(dataDTO.getBuyMoney());
        } else {
            dataDTO.setExcludeMoney(dataDTO.getBuyMoney() - eatMaxValue);
            dataDTO.setEatMoney(eatMaxValue);
        }
    }

    /**
     * 将形如"1:20 2:20 3:10"这类字符串转换成Map
     * 如果该组数据中存在相同的号码，如"1-20 2-20 1-10"，将会对相同号码进行金额累计
     *
     * @param str
     * @return
     */
    public static Map<Integer, Integer> jsonstrToMap(String str) {
        Map<Integer, Integer> map = new HashMap<>();
        String[] strArr = str.split("\\s+");
        for (String s : strArr) {
            String[] res = s.split(":");
            if (map.get(Integer.valueOf(res[0])) == null) {
                map.put(Integer.valueOf(res[0]), Integer.valueOf(res[1]));
            } else {
                log.info("******该组{}数据中，存在至少两个相同的号码[{}]", strArr, Integer.valueOf(res[0]));
                map.put(Integer.valueOf(res[0]), map.get(Integer.valueOf(res[0])) + Integer.valueOf(res[1]));
            }

        }
        return map;
    }

    /**
     * 判断该组号码中是否有重复的号码
     * 还需考虑如2、02这类
     *
     * @param arr
     * @return
     */
    public static boolean hasDuplicates(String[] arr) {
        return Arrays.stream(arr).distinct().count() != arr.length;
        //return Arrays.stream(arr).map(i -> Integer.valueOf(i)).distinct().count() != arr.length;
    }
}
